<?php

namespace app\service;

use app\core\Constant;
use app\core\exception\BusinessException;
use app\core\Service;
use app\core\util\Tree;
use app\model\SysDept;
use app\model\SysRoleDept;
use app\model\SysUser;
use think\facade\Db;

/**
 * @extends Service<DeptService>
 */
class DeptService extends Service
{
    public function getDeptTree()
    {
        $list = SysDept::where('status', Constant::STATUS_NORMAL)
            ->order("parent_id asc")
            ->field("dept_id `key`, dept_name `title`, parent_id")
            ->select()->toArray();
        $tree = [];
        if (count($list) > 0) {
            $tree = Tree::invoke()->buildTree($list, $list[0]['parent_id'], "key");
        }
        return $tree;
    }

    public function list($searchQuery = null)
    {
        $list = SysDept::where('dept_id', '>', 0)->where(function ($q) use ($searchQuery) {
                if (!empty($searchQuery['dept_name'])) {
                    $q = $q->where('dept_name', 'like', "%" . $searchQuery['dept_name'] . "%");
                }
                if (!empty($searchQuery['status'])) {
                    $q->where('status', $searchQuery['status']);
                }
            });

        $pid = $list->order('parent_id asc')->value('parent_id');
        $list = $list->order("order_num desc")->select()->toArray();

        if (count($list) > 0 && empty($searchQuery['dept_name'])) {
            $list = Tree::invoke()->buildTree($list, $pid, "dept_id");
        }

        return $list;
    }

    public function del($dept_id)
    {

        $dept = SysDept::find($dept_id);
        if (!$dept) {
            throw new BusinessException('部门不存在');
        }

        // 判断是否存在子部门
        if (SysDept::where('parent_id', $dept_id)->find()) {
            throw new BusinessException('存在子部门，暂时无法删除');
        }

        // 判断是否有用户关联部门
        if (SysUser::where('dept_id', $dept_id)->find()) {
            throw new BusinessException('存在用户关联部门，暂时无法删除');
        }

        // 删除关联
        Db::startTrans();
        try {
            $dept->delete();
            SysRoleDept::where('dept_id', $dept_id)->delete();
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            throw new BusinessException($e->getMessage());
        }

    }

    public function save($data, $dept_id = null)
    {
        $saveData = [
            'parent_id' => $data['parent_id'],
            'ancestors' => '0',
            'dept_name' => $data['dept_name'],
            'order_num' => $data['order_num'] ?? 99,
            'leader' => $data['leader'] ?? null,
            'phone' => $data['phone'] ?? null,
            'email' => $data['email'] ?? null,
            'status' => $data['status'] ?? '0'
        ];

        if ((int)$saveData['parent_id'] > 0) {
            $parent = SysDept::where('dept_id', $data['parent_id'])->find();
            if (!$parent) {
                throw new BusinessException('上级部门不存在');
            }
            $ancestorsArr = explode(",", $parent['ancestors']);
            if (!empty($dept_id) && in_array($dept_id, $ancestorsArr)) {
                throw new BusinessException('无法将子部门设为上级部门');
            }
            $saveData['ancestors'] = $parent['ancestors'] . "," . $saveData['parent_id'];
        }

        if (empty($dept_id)) {
            $dept = SysDept::create($saveData);
            if (empty($dept->dept_id)) {
                throw new BusinessException('创建失败');
            }
        } else {
            $dept = SysDept::find($dept_id);
            if (!$dept) {
                throw new BusinessException('部门不存在');
            }
            $childs = SysDept::whereFindInSet('ancestors', $dept['dept_id'])
                ->field('dept_id, parent_id, ancestors')
                ->select();
            Db::startTrans();
            try {
                $dept->save($saveData);
                // 更新全部子级部门
                foreach ($childs as $child) {
                    $parent = SysDept::where('dept_id', $child['parent_id'])->find();
                    $child->ancestors = $parent['ancestors'] . "," . $child['parent_id'];
                    $child->save();
                }
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                throw new BusinessException($e->getMessage());
            }
        }
    }

    public function info($dept_id)
    {
        $dept = SysDept::find($dept_id);
        if (!$dept) {
            throw new BusinessException('部门不存在');
        }
        return $dept->toArray();
    }
}